package com.example.administrator.fangbook.customview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by Administrator on 2018/11/10.
 */

/**
 * 侧滑栏
 */
public class ResideLayout extends ViewGroup {

    private ViewDragHelper viewDragHelper;
    //可以滑动的子View
    private View mSlideableView;
    //打开菜单后的宽度 dp
    private int open_menu_with = 150;
    //px
    private int mOverhangSize;
    private int huadongjuli;
    private float mSlideOffset;

    static final SlidingPanelLayoutImpl IMPL;
    /**
     * If no fade color is given by default it will fade to 80% gray.
     */
    private static final int DEFAULT_FADE_COLOR = 0x99000000;
    /**
     * The fade color used for the sliding panel. 0 = no fading.
     */
    private int mSliderFadeColor = DEFAULT_FADE_COLOR;

    public ResideLayout(Context context) {
        this(context, null);
    }

    public ResideLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ResideLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    static {
        IMPL = new SlidingPanelLayoutImplJBMR1();
    }

    private void init(Context context, AttributeSet attrs) {
        //初始化ViewDragHelper
        viewDragHelper = ViewDragHelper.create(this, new ViewDragHelperCall());
        final float density = context.getResources().getDisplayMetrics().density;
        mOverhangSize = (int) (open_menu_with * density + 0.5f);
        //设置检测到的最小速度
        viewDragHelper.setMinVelocity(400 * density);
        viewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
    }

    /**
     * 测量
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //获取父视图指定值View的高的Mode
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        //根据父视图给定的模式得出：本身视图的大小
        int widthSize = getDefaultSize(300, widthMeasureSpec);
        int heightSize = getDefaultSize(300, heightMeasureSpec);
        //得到视图本身的高，和最大的高
        int layoutHeight, maxLayoutHeight = 0;
        switch (heightMode) {
            case MeasureSpec.EXACTLY:
                layoutHeight = maxLayoutHeight = heightSize - getPaddingBottom() - getPaddingTop();
                break;
            case MeasureSpec.AT_MOST:
                maxLayoutHeight = heightSize - getPaddingBottom() - getPaddingTop();
                break;
        }
        //得到可用的宽
        final int widthAvailable = widthSize - getPaddingLeft() - getPaddingRight();
        final int childCount = getChildCount();
        if (childCount > 2) {
            try {
                throw new Exception("只能添加两个视图！");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        for (int i = 0; i < getChildCount(); i++) {
            View childAt = getChildAt(i);
            LayoutParams lp = (LayoutParams) childAt.getLayoutParams();
            int childWidthMode, childHeightMode;
            if (lp.width == LayoutParams.MATCH_PARENT || lp.width == LayoutParams.FILL_PARENT) {
                childWidthMode = MeasureSpec.makeMeasureSpec(widthAvailable, MeasureSpec.EXACTLY);
            } else {
                childWidthMode = MeasureSpec.makeMeasureSpec(widthAvailable, MeasureSpec.AT_MOST);
            }
            if (lp.height == LayoutParams.MATCH_PARENT || lp.width == LayoutParams.FILL_PARENT) {
                childHeightMode = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.EXACTLY);
            } else {
                childHeightMode = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.AT_MOST);
            }
            childAt.measure(childWidthMode, childHeightMode);
            if (i != 0) {
                lp.slideable = true;
                mSlideableView = childAt;
            }
        }
        setMeasuredDimension(widthSize, heightSize);

    }

    /**
     * 指定子View的位置
     *
     * @param changed
     * @param l
     * @param t
     * @param r
     * @param b
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        for (int i = 0; i < getChildCount(); i++) {
            View childAt = getChildAt(i);
            if (childAt.getVisibility() == View.GONE) {
                continue;
            }
            LayoutParams lp = (LayoutParams) childAt.getLayoutParams();
            if (lp.slideable) {
                //求出滑动距离  父视图的panddingleft + 子view的Margin
                int with = r - l;
                huadongjuli = with - getPaddingRight() - lp.rightMargin - lp.leftMargin - getPaddingLeft() - mOverhangSize;

            }
            childAt.layout(l, t, r, b);
        }
    }

    @Override
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return new LayoutParams(p);
    }

    @Override
    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new LayoutParams(getContext(), attrs);
    }

    class LayoutParams extends MarginLayoutParams {

        //是否可以滑动
        public boolean slideable;
        public Paint dimPaint;

        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
        }

        public LayoutParams(int width, int height) {
            super(width, height);
        }

        public LayoutParams(MarginLayoutParams source) {
            super(source);
        }

        public LayoutParams(ViewGroup.LayoutParams source) {
            super(source);
        }
    }

    class ViewDragHelperCall extends ViewDragHelper.Callback {

        /**
         * 那个ziview滑动
         *
         * @param child
         * @param pointerId
         * @return
         */
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return ((LayoutParams) child.getLayoutParams()).slideable;
        }

        /**
         * 处理滑动边界
         *
         * @param child
         * @param left
         * @param dx
         * @return
         */
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams();
            int newLeft;
            //开始移动的点x
            int startX = lp.leftMargin + getPaddingLeft();
            //结束的点x
            int endX = startX + huadongjuli;
            newLeft = Math.min(Math.max(left, startX), endX);
            Log.e("clampViewPosi", "left==" + left + ",,,,dx==" + dx);
            return newLeft;
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            return child.getTop();
        }

        /**
         * 处理手指释放回弹
         *
         * @param releasedChild
         * @param xvel
         * @param yvel
         */
        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
            Log.e("onViewReleased", "xvel==" + xvel + ",,yvel==" + yvel);
            int left = 0;
            if (xvel > 0) {
                left += huadongjuli;
            }
            viewDragHelper.settleCapturedViewAt(left, releasedChild.getTop());
            invalidate();
        }

        /**
         * 没看出这个方法的区别，添加不添加一个模样
         *
         * @param edgeFlags
         * @param pointerId
         */
        @Override
        public void onEdgeDragStarted(int edgeFlags, int pointerId) {
            super.onEdgeDragStarted(edgeFlags, pointerId);
            viewDragHelper.captureChildView(mSlideableView, pointerId);
        }


        /**
         * 位置变化时回调
         * 设置推动View的 明亮度
         *
         * @param changedView
         * @param left
         * @param top
         * @param dx
         * @param dy
         */
        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            super.onViewPositionChanged(changedView, left, top, dx, dy);
            setMenuViewTone(left);
        }
    }

    private void setMenuViewTone(int newLeft) {

        final int newStart = newLeft;
        final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams();
        final int paddingStart = getPaddingLeft();
        final int lpMargin = lp.leftMargin;
        final int startBound = paddingStart + lpMargin;
        mSlideOffset = (float) (newStart - startBound) / huadongjuli;

        if (lp.slideable) {
            if (mSlideOffset > 0 && mSliderFadeColor != 0) {
                final int baseAlpha = (mSliderFadeColor & 0xff000000) >>> 24;
                int imag = (int) (baseAlpha * mSlideOffset);
                int color = imag << 24 | (mSliderFadeColor & 0xffffff);
                if (lp.dimPaint == null) {
                    lp.dimPaint = new Paint();
                }
                lp.dimPaint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_OVER));
                if (ViewCompat.getLayerType(mSlideableView) != ViewCompat.LAYER_TYPE_HARDWARE) {
                    ViewCompat.setLayerType(mSlideableView, ViewCompat.LAYER_TYPE_HARDWARE, lp.dimPaint);
                }
                invalidateChildRegion(mSlideableView);
            } else if (ViewCompat.getLayerType(mSlideableView) != ViewCompat.LAYER_TYPE_NONE) {
                if (lp.dimPaint != null) {
                    lp.dimPaint.setColorFilter(null);
                }
                final DisableLayerRunnable dlr = new DisableLayerRunnable(mSlideableView);
                ViewCompat.postOnAnimation(this, dlr);
            }
        }

    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (viewDragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

//    @Override
//    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
//        boolean result;
//        LayoutParams lp = (LayoutParams) child.getLayoutParams();
////        final int save = canvas.save(Canvas.ALL_SAVE_FLAG);
//        final int save = canvas.save();
//        if (!lp.slideable && mSlideableView != null) {
//            canvas.scale(1.5f - 0.5f * mSlideOffset, 1.5f - 0.5f * mSlideOffset, child.getRight(), getHeight() / 2);
//        } else {
//            canvas.scale(1 - mSlideOffset / 5, 1 - mSlideOffset / 5, mSlideableView.getLeft(), getHeight() / 2);
//            ViewCompat.setRotationY(child, -10 * mSlideOffset);
//        }
//        result = super.drawChild(canvas, child, drawingTime);
//        canvas.restoreToCount(save);
//        return result;
//    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        viewDragHelper.shouldInterceptTouchEvent(ev);
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        viewDragHelper.processTouchEvent(event);
        return true;
    }


    private class DisableLayerRunnable implements Runnable {
        final View mChildView;

        DisableLayerRunnable(View childView) {
            mChildView = childView;
        }

        @Override
        public void run() {
            if (mChildView.getParent() == ResideLayout.this) {
                ViewCompat.setLayerType(mChildView, ViewCompat.LAYER_TYPE_NONE, null);
                invalidateChildRegion(mChildView);
            }
        }
    }

    private void invalidateChildRegion(View mChildView) {
        IMPL.invalidateChildRegion(this, mChildView);
    }

    interface SlidingPanelLayoutImpl {
        void invalidateChildRegion(ResideLayout parent, View child);
    }

    static class SlidingPanelLayoutImplBase implements SlidingPanelLayoutImpl {
        @Override
        public void invalidateChildRegion(ResideLayout parent, View child) {
            ViewCompat.postInvalidateOnAnimation(parent, child.getLeft(), child.getTop(), child.getRight(), child.getBottom());
        }
    }

    /**
     * 实现明暗的调整
     */
    static class SlidingPanelLayoutImplJBMR1 extends SlidingPanelLayoutImplBase {
        @Override
        public void invalidateChildRegion(ResideLayout parent, View child) {
            ViewCompat.setLayerPaint(child, ((LayoutParams) child.getLayoutParams()).dimPaint);
        }
    }
}
